package com.example.listener;

import com.example.service.other.UserSeckillValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import com.example.mapper.GoodsMapper;
import com.example.entity.SeckillMessage;
import com.example.entity.SeckillResult;
import com.example.service.impl.OrderService;
import com.example.service.other.SseService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.amqp.rabbit.annotation.RabbitListener;

import static com.example.entity.constant.mq.RabbitmqConstant.SECKILL_QUEUE;
import static com.example.entity.constant.redis.SeckillConstant.RESULT_KEY_PREFIX;

//监听秒杀核心队列
@Component
public class SeckillMessageConsumer {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private OrderService orderService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private UserSeckillValidator userValidator;

    @Autowired
    private SseService sseService;

    @Autowired
    private ObjectMapper objectMapper;

    @RabbitListener(
            queues = SECKILL_QUEUE,
            errorHandler = "seckillErrorHandler", // 异常处理器
            containerFactory = "rabbitListenerContainerFactory" // 重试拦截器，超次数进死信队列
    )
    public void handleSeckillMessage(SeckillMessage message) {
        Long userId = message.getUserId();
        Long goodsId = message.getGoodsId();
        String token = message.getToken();
        String resultKey = RESULT_KEY_PREFIX + token;

        SeckillResult result = new SeckillResult();
        result.setToken(token);

        try {
            // 1. 数据库乐观锁扣减库存
            int rows = goodsMapper.decreaseStock(goodsId);
            if (rows <= 0) {
                // 库存不足：标记失败，清除用户记录
                result.setStatus("FAIL");
                result.setMessage("抱歉，商品已抢完~");
                redisTemplate.opsForValue().set(resultKey, "FAIL", 24, java.util.concurrent.TimeUnit.HOURS);
                userValidator.clearUserRecord(userId, goodsId);
            } else {
                // 2. 库存扣减成功，创建订单
                String orderId = orderService.createOrder(userId, goodsId, token);

                // 3. 标记成功
                result.setStatus("SUCCESS");
                result.setMessage("恭喜，秒杀成功！");
                result.setOrderId(orderId);
                redisTemplate.opsForValue().set(resultKey, "SUCCESS", 24, java.util.concurrent.TimeUnit.HOURS);
            }

            // 4. 推送结果给前端
            sseService.pushSeckillResult(token, objectMapper.writeValueAsString(result));

        } catch (Exception e) {
            // 异常处理：标记失败，清除用户记录
            try {
                result.setStatus("FAIL");
                result.setMessage("系统繁忙，请稍后再试");
                redisTemplate.opsForValue().set(resultKey, "FAIL", 24, java.util.concurrent.TimeUnit.HOURS);
                userValidator.clearUserRecord(userId, goodsId);

                // 推送失败结果
                sseService.pushSeckillResult(token, objectMapper.writeValueAsString(result));
            } catch (Exception ex) {
                // 忽略序列化异常
            }
        }
    }
}


